package com.ht.callback.init;

import java.util.List;
import java.util.Set;

import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.util.RedisUtil;
import com.ht.callback.annotation.HtFunction;
import com.ht.callback.util.FunctionUtil;
import com.ht.cdc.CdcConfig;
import com.ht.cdc.CdcHelper;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;

/**
 * 项目启动后要做的操作
 * @author asq
 * @createTime 2024年12月17日 10:47:07
 */
@Slf4j
@Component
public class ApplicationInitializer {
	@Autowired
	private CdcHelper cdcHelper;
	
	//加载全部有@HtFunction注解的接口，将所有实现类加载到{@link FunctionUtil}工具类中
	@PostConstruct
	private void loadHtFunctionList() {
		log.info("[init]函数扫描加载开始...");
        try {
            // 创建Reflections对象
            Reflections reflections = new Reflections("com.ht.callback");
            
            // 获取包下面的所有有@HtFunction注解的类
            Set<Class<?>> interfaces = reflections.getTypesAnnotatedWith(HtFunction.class);
            for (Class<?> interfaceClass : interfaces) {
                // 验证是否是接口
                if (!interfaceClass.isInterface()) {
                    continue;
                }
                
                // 获取该接口的所有实现类
                Set<?> implementations = reflections.getSubTypesOf(interfaceClass);
                
                // 遍历实现类并实例化
                for (Object impl : implementations) {
                	Class<?> implClass = (Class<?>) impl;
                    try {
                        FunctionUtil.setFunction(implClass.getSimpleName(), implClass.getDeclaredConstructor().newInstance());
                        log.info("[init]加载函数成功: {}", implClass.getName());
                    } catch (Exception e) {
                        log.error("[init]加载函数失败: {}, 错误: {}", implClass.getName(), e.getMessage(), e);
                    }
                }
            }
                        
        } catch (Exception e) {
            log.error("[init]函数扫描加载失败: {}", e.getMessage(), e);
        }
		log.info("[init]函数扫描加载结束~");
    }
	
	// 启动CDC任务
	@PostConstruct
	private void startCDC() {
		// 查询所有cdc数据源
		List<Entity> list = Db.createSqlParser("open_app").where("cdc_status", CdcConfig.NORMAL).query();
        log.info("[cdc]扫描open_app表，需要启动的cdc任务数: {}", list.size());
		list.stream().forEach(openApp -> {
			JSONObject appConfig = JSONUtil.parseObj(openApp.getStr("config"));
			JSONObject config = appConfig.getJSONObject("cdc_config");
			CdcConfig cdcConfig = CdcConfig.create(config);
			long tenantId = openApp.getLong("tenant_id");
			String appId = openApp.getStr("main_id");
			String name = openApp.getStr("name");
			try {
				// 删除“运行中”的标志，恢复为未运行
				RedisUtil.delete(String.format(CdcHelper.KEY_CDC_RUNING, appId));
				
				// 运行任务
				cdcHelper.start(cdcConfig, tenantId, appId);
				log.info("[cdc]启动任务成功，租户ID：{}，cdc名称：{}", tenantId, name);
			} catch (Exception e) {
	            log.error("[cdc]启动任务失败: {}", e.getMessage(), e);
			}
		});
	}
}
